package com.loser.module.base.common.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.loser.module.base.mq.gateway.GateWayConst;
import com.loser.module.base.proto.CmdBeanUtils;
import com.loser.module.base.proto.broadcast.BaseBroadCast;
import com.loser.module.base.proto.broadcast.BroadCastMsg;
import com.loser.utils.ContextUtil;
import com.loser.utils.SerializationUtil;
import com.loser.utils.trace.TraceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class BroadCastUtils {

    static final Logger log = LoggerFactory.getLogger(BroadCastUtils.class);

    private static RabbitTemplate rabbitTemplate;

    private static RabbitTemplate getRabbitTemplate() {

        if (Objects.nonNull(rabbitTemplate)) {
            return rabbitTemplate;
        }
        synchronized (BroadCastUtils.class) {
            if (Objects.isNull(rabbitTemplate)) {
                rabbitTemplate = ContextUtil.getBean(RabbitTemplate.class);
            }
        }
        return rabbitTemplate;

    }

    private BroadCastUtils() {
    }

    public static void sendBroadCast2All(BaseBroadCast broadCast) {

        if (Objects.isNull(broadCast)) {
            return;
        }
        doSend(broadCast, 1, Collections.emptyList(), null);
        log.info("sendBroadCast2All data {} ", broadCast);

    }

    public static void sendBroadCast2Area(BaseBroadCast broadCast, String roomType) {
        sendBroadCast2Area(broadCast, Collections.singletonList(roomType));
    }

    public static void sendBroadCast2Area(BaseBroadCast broadCast, List<String> areas) {

        if (Objects.isNull(broadCast) || CollectionUtil.isEmpty(areas)) {
            return;
        }
        doSend(broadCast, 2, areas, null);
        log.info("sendBroadCast2Area data {} ids {} ", broadCast, areas);

    }

    public static void sendBroadCast2Room(BaseBroadCast broadCast, String roomType, Long roomId) {
        sendBroadCast2Room(broadCast, roomType, Collections.singletonList(roomId));
    }

    public static void sendBroadCast2Room(BaseBroadCast broadCast, String roomType, List<Long> roomIds) {

        if (Objects.isNull(broadCast) || StrUtil.isEmpty(roomType) || CollectionUtil.isEmpty(roomIds)) {
            return;
        }
        List<String> ids = roomIds.stream().distinct().map(Convert::toStr).collect(Collectors.toList());
        doSend(broadCast, 3, ids, roomType);
        log.info("sendBroadCast2Room data {} ids {}", broadCast, ids);

    }

    public static void sendBroadCast2user(BaseBroadCast broadCast, Long userId) {
        sendBroadCast2user(broadCast, Collections.singletonList(userId));
    }

    public static void sendBroadCast2user(BaseBroadCast broadCast, List<Long> userIds) {

        if (Objects.isNull(broadCast) || CollectionUtil.isEmpty(userIds)) {
            return;
        }
        List<String> uIds = userIds.stream().distinct().map(Convert::toStr).collect(Collectors.toList());
        doSend(broadCast, 4, uIds, null);
        log.info("sendBroadCast2user data {} userIds {}", broadCast, uIds);

    }

    private static void doSend(BaseBroadCast broadCast, int type, List<String> ids, String roomType) {

        BroadCastMsg msg = new BroadCastMsg();
        msg.setType(type);
        msg.setTraceId(TraceUtil.getTraceId());
        msg.setTypeCmd(CmdBeanUtils.getByClass(broadCast.getClass()));
        msg.setMessage(SerializationUtil.serializeToByte(broadCast));
        msg.setTargetIds(ids);
        msg.setRoomType(roomType);
        RabbitTemplate template = getRabbitTemplate();
        template.convertAndSend(GateWayConst.BroadCast.exchange, GateWayConst.BroadCast.routeKey, msg);

    }

}
